#include "StdAfx.h"
#include "WarnAction.h"
#include "Level1Warning.h"
#include "Level2Warning.h"
#include "Level3Warning.h"
#include "Level4Warning.h"
#include "AivReportWarning.h"

CWarnAction::CWarnAction(unsigned int diff, QString page, QString author):m_rollback(diff, page),
	m_author(author),m_page(page),
	rollbackChain(new CLevel1Warning(new CLevel2Warning(new CLevel3Warning(new CLevel4Warning(new CAivReportWarning)))))
{
	// Hook up all signals as pass-through
	connect(&m_rollback, SIGNAL(RollbackSucceeded(unsigned int)), SLOT(EmitRollbackSucceeded(unsigned int)));
	connect(&m_rollback, SIGNAL(RollbackFailed(unsigned int, QString, QString)), SLOT(EmitRollbackFailed(unsigned int, QString, QString)));
	connect(&m_rollback, SIGNAL(EventPosted(CLoggedEvent*)), SLOT(EmitEventPosted(CLoggedEvent*)));
}

CWarnAction::~CWarnAction(void)
{
	delete rollbackChain;
}

bool CWarnAction::Run()
{
	CLoggedEvent *evt = new CLoggedEvent(CLoggedEvent::INFO, "Revert & warn", "Waiting for rollback operation");
	emit EventPosted(evt);

	// First try to rollback
	bool success = ExecuteRollback();
	if (success)
	{
		// Succeeded rolling back, so warn user
				
		// Look up user page
		evt->UpdateMessage("Loading user page of " + m_author);
		QString loadUrl;
		QTextStream stream(&loadUrl);
		// TODO: Site I18N
		stream << "http://en.wikipedia.org/w/api.php?action=query&prop=revisions&titles=User%20talk:"
			<< QUrl::toPercentEncoding(m_author) << "&export=1&exportnowrap=1";
		QUrl loadUri(loadUrl);

		QNetworkAccessManager &manager = CollabRC::GetNetworkManager();
		QNetworkRequest request = CollabRC::CreateNetworkRequest(loadUri);
		QNetworkReply *reply = manager.get(request);

		// Wait for response
		QEventLoop loop;
		loop.connect(reply, SIGNAL(finished()), SLOT(quit()));
		loop.exec();

		// Load the result
		CMediawikiXmlReader handler(NULL);
		QXmlSimpleReader reader;
		reader.setContentHandler(&handler);
		reader.parse(QXmlInputSource(reply));

		if (!handler.errorOccurred())
		{
			// Issue warning
			evt->UpdateMessage("Issuing warning to " + m_author);
			success = rollbackChain->GiveWarning(m_author, handler.GetText(), m_page);

			if (success)
			{
				evt->UpdateStatus(CLoggedEvent::COMPLETE);
				evt->UpdateMessage("Issued warning to " + m_author);
			}
			else 
			{
				evt->UpdateStatus(CLoggedEvent::ERROR);
				evt->UpdateMessage("Failed to issue warning");
			}
		}
		else 
		{
			// TODO: Gracefully handle error
		}
	}

	//evt->deleteLater();
	// TODO: Prevent this memory leak

	return success;
}

void CWarnAction::EmitRollbackSucceeded( unsigned int diff )
{
	emit RollbackSucceeded(diff);
}

void CWarnAction::EmitRollbackFailed( unsigned int diff, QString errorCode, QString errorMessage )
{
	emit RollbackFailed(diff, errorCode, errorMessage);
}

void CWarnAction::EmitEventPosted( CLoggedEvent* event )
{
	emit EventPosted(event);
}